﻿package iamjason.tweener
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.EventDispatcher;
	import flash.utils.Timer;
	import flash.utils.Dictionary;
	import flash.events.TimerEvent;
	/**
	 * 使用Timer來進行GoFrame的類別
	 * 
	 * @author Jason Tseng
	 */
	public class GoFrameTimer extends EventDispatcher
	{
		private static var _list:Dictionary = new Dictionary(true);
		private var _toFrame:int;
		private var _timer:Timer;
		private var _spf:Number;
		private var _mc:Object;
		private var _funtion:Function;
		private var _args:Array;
		
		/**
		 * 建構子, 產生一個GoFrameTimer的instance<br>
		 * 通常不直接透過建構子產生, 而是使用GoFrameTimer.go的靜態method<br>
		 * 可以在結束後自動釋放資源
		 * 
		 * @param	pMC			目標MovieClip
		 * @param	pFrame		目標frame
		 * @param	pSPF		多快跳一格frame (單位是mini-second)
		 * @param	pOnComplete	結束後要呼叫的function
		 * @param	pArgs		要帶給pOnComplete的參數
		 */
		public function GoFrameTimer(pMC:Object, pFrame:int, pSPF:Number = 0, pOnComplete:Function = null, pArgs:Array = null):void {
			_mc = pMC;
			_toFrame = pFrame;
			_funtion = pOnComplete;
			_args = pArgs;
			
			if (_toFrame < 1)
				_toFrame = 1;
			if (_toFrame > _mc.totalFrames)
				_toFrame = _mc.totalFrames;
			
			if (pSPF == 0) {
				if (_mc.stage != null)
					_spf = 1000 / _mc.stage.frameRate;
				else
					_spf = 1000 / 45;
			} else
				_spf = pSPF
			
			_timer = new Timer(_spf);
			_timer.addEventListener(TimerEvent.TIMER, timerEvent);
			_timer.start();
		}
		
		/**
		 * 靜態方法, 通常使用此方法來進行GoFrame
		 * 
		 * @param	pMC			目標MovieClip
		 * @param	pFrame		目標frame
		 * @param	pSPF		多快跳一格frame (單位是mini-second)
		 * @param	pOnComplete	結束後要呼叫的function
		 * @param	pArgs		要帶給pOnComplete的參數
		 * @return	回傳一個GoFrameTimer instance
		 */
		public static function go(pMC:Object, pFrame:int, pSPF:Number = 0, pOnComplete:Function = null, pArgs:Array = null):GoFrameTimer {
			if (_list[pMC] != undefined) {
				_list[pMC].destroy();
				_list[pMC] = null;
				delete _list[pMC];
			}
			var _instance:GoFrameTimer = new GoFrameTimer(pMC, pFrame, pSPF, pOnComplete, pArgs);
			_list[pMC] = _instance;
			return _instance;
		}
		
		private function timerEvent(e:TimerEvent):void {
			if (_toFrame > _mc.currentFrame)
				_mc.nextFrame();
			if (_toFrame < _mc.currentFrame)
				_mc.prevFrame();
			
			if (_toFrame == _mc.currentFrame)
				goComplete();
		}
		
		private function goComplete():void {
			_timer.stop();
			
			if (_funtion != null)
				_funtion.apply(null, _args);
			
			GoFrameTimer.removeTween(_mc);
		}
		
		/**
		 * 靜態方法, 移除某一個MovieClip上的GoFrameTimer行為
		 * 
		 * @param	pMC	目標MovieClip
		 */
		public static function removeTween(pMC:Object):void {
			if (_list[pMC] != undefined) {
				_list[pMC].destroy();
				_list[pMC] = null;
				delete _list[pMC];
			}
		}
		
		public function destroy():void {
			if (_timer == null)
				return;
			
			_timer.stop();
			_timer.removeEventListener(TimerEvent.TIMER, timerEvent);
			_timer = null;
			_funtion = null;
			_args = null;
			_mc = null;
		}
	}
	
}